package com.gzcstec.order.controller;

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;

/**
 * hystrix测试
 */
@RestController
@DefaultProperties(defaultFallback = "defaultFallback")
public class HystrixController {

//    @HystrixCommand(defaultFallback = "fallback" , commandProperties = {
//            //设置超时时间，默认超时时间为1秒
//         @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds" , value = "3000")
//    })


    @HystrixCommand(defaultFallback = "fallback" , commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled" , value = "true"),                  //打开熔断机制
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold" , value = "10"),   //在滚动时间内，熔断请求数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds" , value = "10000"),//滚动休眠窗口时间 毫秒
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage" , value = "60")  //滚动时间内，打开熔断机制的错误百分比
            //说明 在10个请求，如果有百分之60的请求返回错误结果，则打开熔断，此期间降级成为主业务
            // 在滚动时间周期过去之后，进入版熔断状态，释放请求到主业务，
            // 如果请求返回错误则继续进行滚动休眠时间，熔断继续打开
            // 如果请求返回成功，并且错误率下降到60%，则关闭熔断，请求继续发送到主业务
    })
    //读取配置文件的hystrix的配置信息
//    @HystrixCommand
    @GetMapping("/getProductList")
    public String getProductList(@RequestParam("number") Integer number) {
        //模拟当number为偶数，返回正确结果
        if(number % 2 == 0) {
            return "success";
        }
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.postForObject("http://localhost:8081/product/listForOrder" , Arrays.asList("001") ,
                String.class);
        //服务降级可以用于自身服务错误处理
//        throw new RuntimeException("系统发生异常");
    }

    /**
     * 服务降级的回调方法
     * 这个为核心业务，做降级处理
     * @return
     */
    public String fallback() {
        return "哎呦喂~正在排队中。";
    }

    /**
     * 默认降级的方式
     * 一般普通业务的降级处理方式，跳转到静态页面
     * @return
     */
    public String defaultFallback() {
        return "默认提示：哎呦喂~又在排队中。";
    }

}
